﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;

namespace StuMana.UI
{
    public partial class CheckInOut : Form
    {
       


        string ProPath;
        byte[] serial_buff = new byte[40];
        Services.SL025M rfid_reader = new Services.SL025M();
        Services.COM connect;
        private Bitmap image;
        private System.Windows.Forms.Timer readTimer;
        private string tag = "";
        private Boolean isSelect = false;
        private Services.student print_std = new Services.student();
        // get size of return byteArray
        private int size;


        public delegate void AsyncCallback(IAsyncResult ar);
        public delegate void AddTolstDiscoveredDevices(object o);

        private UdpState GlobalUDP;

        /// <summary>
        ///  UDP
        /// </summary>
        struct UdpState
        {
            public System.Net.IPEndPoint EP;
            public System.Net.Sockets.UdpClient UDPClient;
        }

        private void cmdDiscoverDevices_Click(object sender, EventArgs e)
        {
            try
            {
                // Try to send the discovery request message
                byte[] DiscoverMsg = Encoding.ASCII.GetBytes("IP + Mac+   Discovery: Who is out there?");
                
                GlobalUDP.UDPClient.Send(DiscoverMsg, DiscoverMsg.Length, new System.Net.IPEndPoint(System.Net.IPAddress.Parse("255.255.255.255"), 30303));
            }
            catch
            {
                MessageBox.Show("Unable to transmit discovery message.  Check network connectivity and ensure that no other instances of this program are running.", "Error", MessageBoxButtons.OK);
                return;
            }
        }


        public void ReceiveCallback(IAsyncResult ar)
        {
            UdpState MyUDP = (UdpState)ar.AsyncState;

            // Obtain the UDP message body and convert it to a string, with remote IP address attached as well
            if (Start.Text == "Stop")
            {
                try
                {
                    string ReceiveString = Encoding.ASCII.GetString(MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP));
                    ReceiveString = ReceiveString.Replace("\r\n", "\n");

                    Byte[] receiBytes = MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP);

                    StringBuilder hex = new StringBuilder(receiBytes.Length * 2);
                    for (int i = 6; i < 12; i++) hex.AppendFormat("{0:x2}", receiBytes[i]);

                    string macAddress = hex.ToString();
                    string ip = MyUDP.EP.Address.ToString();

                   
                    byte[] arrSrc = {MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP)[0],MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP)[1] };
                    string srcPort = Encoding.ASCII.GetString(arrSrc);
                    

                    byte[] arrDes = { MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP)[2], MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP)[3] };
                    string desPort = Encoding.ASCII.GetString(arrDes);

                    byte[] arrLength = { MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP)[4], MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP)[5] };
                    int length = BitConverter.ToInt32(arrLength, 0);

                    byte[] arrCheckSum = { MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP)[6], MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP)[7] };
                    string checkSum = Encoding.ASCII.GetString(arrCheckSum);

                    string data = "";
                    int lengthData = length - 8;
                    if (lengthData > 0)
                    {
                        byte[] arrData = new byte[lengthData];
                        for (int i = 0; i < lengthData; i++)
                        {
                            arrData[i] = MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP)[8+i];
                        }

                        data = Encoding.ASCII.GetString(arrData);

                     //   label1.Text = data;
                    }
                    //label1.Text = data;
                   



                    // Configure the UdpClient class to accept more messages, if they arrive
                    MyUDP.UDPClient.BeginReceive(ReceiveCallback, MyUDP);


                    //ts_label.Text = ReceiveString;
                    serial_buff = FromHex(ReceiveString);
                    tag = get_student_tagID().ToString();

                    p_CheckInOut.Invoke(new AddTolstDiscoveredDevices(show_stdInfo), tag);
                }
                catch (Exception e)
                {

                    MessageBox.Show(e.Message, "Warning");
                }
            }
           // show_stdInfo(tag);

        }

        public static byte[] FromHex(string hex)
        {
            hex = hex.Replace("-", "");
            byte[] raw = new byte[hex.Length / 2];
            for (int i = 0; i < raw.Length; i++)
            {
                raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
            }
            return raw;
        }
        /*--------------------------------------------------------------*/

        public CheckInOut()
        {
            InitializeComponent();
            CheckInOut_initial();
        }

        public Panel getPanel(int x, int y)
        {
            p_CheckInOut.Location = new Point(x, y);
            return p_CheckInOut;
        }

        // user initial 
        private void CheckInOut_initial()
        {
            // get project directory
            ProPath = Environment.CurrentDirectory;

            //pictureBox 
            ProPath += "\\images\\logo.jpg";
            image = new Bitmap(Image.FromFile(ProPath), new Size(pictureBox1.Width, pictureBox1.Height));
            pictureBox1.Image = image;

            //timer setting
            readTimer = new System.Windows.Forms.Timer();
            readTimer.Interval = 200;
            readTimer.Tick += new EventHandler(readTimer_Tick);
            
            ts_label.Text = "Check InOut OFF";

            //button
            bt_fullscreen.Enabled = false;

            
        }

        // timer event handler
        private void readTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                rfid_reader.selectCard();
                size = connect.getdata(serial_buff);
                // login
                if (serial_buff[3] != 0x01 && size != 5000 && isSelect == false)
                {
                    ts_label.Text = "Checking";
                    readTimer.Enabled = false;

                    // login to tag
                    rfid_reader.LogIn();
                    size = connect.getdata(serial_buff);

                    // ReadData from tag
                    if (serial_buff[3] == 0x02 && size != 5000)
                        rfid_reader.ReadData();
                    else
                    {
                        readTimer.Enabled = true;
                        throw new Exception("Login fail");
                    }
                    size = connect.getdata(serial_buff);

                    //Receive data
                    if (serial_buff[3] == 0x00 && size != 5000)
                    {
                        tag = get_student_tagID().ToString();
                        show_stdInfo(tag);
                        isSelect = true;
                    }
                    else
                    {
                        readTimer.Enabled = true;
                        throw new Exception("Data isn't received");
                    }

                    readTimer.Enabled = true;
                }
                else if (serial_buff[3] == 0x01)
                {
                    isSelect = false;
                }
                else if (size == 5000)
                    ts_label.Text = "No Signal";

            }
            catch (Exception es)
            {
                string msg = es.Message;
                // MessageBox.Show(es.Message,"Read Tag Fail");
            }
        }
        // change tagID into 
        private Int32 get_student_tagID()
        {

            Byte[] temp_byte = { 0x00, 0x00, 0x00, 0x00 };
            temp_byte[2] = serial_buff[6];
            temp_byte[1] = serial_buff[5];
            temp_byte[0] = serial_buff[4];
            Int32 temstr = BitConverter.ToInt32(temp_byte, 0);
            return temstr;
        }
        public void show_stdInfo(object o)
        {
            string tagID = (string)(o);
            try
            {
                if (print_std.getStdInfo(tagID))
                {
                    // change stt inout in database
                    print_std.change_stt(tagID);

                    //Insert to database the information of check in-out
                    print_std.AddNewActivity();


                    //show info to FORM
                    lblTagID.Text = print_std.TagID.ToString();
                    lblFullName.Text = print_std.Name;
                    lblClass.Text = print_std.Class;
                    lblGender.Text = print_std.Gender;
                    if (!print_std.InOut)
                        lblStatus.Text = "VÀO";
                    else
                        lblStatus.Text = "RA";
                    ProPath = Environment.CurrentDirectory;
                    ProPath += "\\images\\" + lblTagID.Text + ".jpg";
                    image = new Bitmap(Image.FromFile(ProPath), new Size(pictureBox1.Width, pictureBox1.Height));
                    pictureBox1.Image = image;
                }
                else
                    resetForm();
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
                //MessageBox.Show("Loi tai CheckInOut.show_stdInfo()\n"+ex.Message, "Error");
                ProPath = Environment.CurrentDirectory;
                ProPath += "\\images\\logo.jpg";
                image = new Bitmap(Image.FromFile(ProPath), new Size(pictureBox1.Width, pictureBox1.Height));
                pictureBox1.Image = image;
            }
        }

        // form reset
        private void resetForm()
        {
            lblTagID.Text = "None";
            lblFullName.Text = "None";
            lblClass.Text = "None";
            lblGender.Text = "None";
            lblStatus.Text = "NONE";
            ProPath = Environment.CurrentDirectory;
            ProPath += "\\images\\logo.jpg";
            image = new Bitmap(Image.FromFile(ProPath), new Size(pictureBox1.Width, pictureBox1.Height));
            pictureBox1.Image = image;
        }

        private void Start_Click(object sender, EventArgs e)
        {
            if (Start.Text == "Start")
            {
                try
                {
                    GlobalUDP.UDPClient = new UdpClient();
                    GlobalUDP.EP = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("255.255.255.255"), 30303);
                    System.Net.IPEndPoint BindEP = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 30303);


                    // Set the local UDP port to listen on
                    GlobalUDP.UDPClient.Client.Bind(BindEP);

                    // Enable the transmission of broadcast packets without having them be received by ourself
                    GlobalUDP.UDPClient.EnableBroadcast = true;
                    GlobalUDP.UDPClient.MulticastLoopback = false;

                    // Configure ourself to receive discovery responses
                    GlobalUDP.UDPClient.BeginReceive(ReceiveCallback, GlobalUDP);




                    
                    // Transmit the discovery request message
                    ts_label.Text = "Wifi listenning";
                    Start.Text = "Stop";
                }
                catch
                {
                    MessageBox.Show("Unable to transmit discovery message.  Check network connectivity and ensure that no other instances of this program are running.", "Error", MessageBoxButtons.OK);
                    return;
                }
            }
            else
            {
                GlobalUDP.UDPClient.Client.Dispose();
                Start.Text = "Start";
                ts_label.Text = "None";
            }

            /*
            if (readTimer.Enabled)
            {
                ts_label.Text = "Check InOut OFF";
                readTimer.Enabled = false;
            }
            else
            {
                ts_label.Text = "Checking";
                readTimer.Enabled = true;
            }
             * */
        }

        // Initial COM connecting
        public void InitialConnect(StuMana.Services.COM conn)
        {
            connect = conn;
            rfid_reader.conn = conn.serialPort;
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void label7_Click(object sender, EventArgs e)
        {

        }

        private void label6_Click(object sender, EventArgs e)
        {

        }

        private void groupBox3_Enter(object sender, EventArgs e)
        {

        }


        
    }
}
